#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "Base64.cpp"
#include "RSA1.cpp"
#define MYPORT 3490
#define BACKLOG 10
#define MAXDATASIZE 1000
using namespace std;
int main()
{
	int sockfd,new_fd,numbytes;
	char buf[MAXDATASIZE];
	struct sockaddr_in my_addr;
	struct sockaddr_in their_addr;
	socklen_t sin_size;
	if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
		perror("socket error");
		exit(1);
	}
	my_addr.sin_family=AF_INET;
	my_addr.sin_port=htons(MYPORT);
	my_addr.sin_addr.s_addr=INADDR_ANY;
	bzero(&(my_addr.sin_zero),sizeof(my_addr.sin_zero));
	if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
		perror("bind error");
		exit(1);
	}
	if(listen(sockfd,BACKLOG)==-1){
		perror("listen error");
		exit(1);
	}
	while(1){
		sin_size=sizeof(struct sockaddr_in);
		if((new_fd=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size))==-1){
			perror("accept");
			continue;
		}
		printf("Server:got connection from %s\n",inet_ntoa(their_addr.sin_addr));
		if(!fork()){
			if(send(new_fd,"Hello, world!\n",14,0)==-1)
				perror("send error");
			close(new_fd);
			exit(0);
		}
		if((numbytes=recv(new_fd,buf,MAXDATASIZE,0))==-1){
			perror("recv");
			exit(1);
		}
		buf[numbytes]='\0';
		ifstream fin;
		string str(buf);
		fin.open("key.txt");
		int d1,n1;
		fin>>d1>>n1;
		string res=RSA_Decrypt(d1,n1,str);
		char * dec_output = Base64Decode((char *)res.c_str(), res.size(), true);
		cout<<"Received: "<<dec_output<<endl;
		close(new_fd);
		fin.close();
		while(waitpid(-1,NULL,WNOHANG)>0);
	}
	return 0;
}